#include "test_list.h"


#ifdef TEST_VARIANT_ITERATOR

//#include "disable_warning.h"

#include "tools/variant.h"



#define TEST_VARIANT_ITERATOR_000
#define TEST_VARIANT_ITERATOR_001
#define TEST_VARIANT_ITERATOR_002
#define TEST_VARIANT_ITERATOR_003
#define TEST_VARIANT_ITERATOR_004
#define TEST_VARIANT_ITERATOR_005
#define TEST_VARIANT_ITERATOR_006
#define TEST_VARIANT_ITERATOR_007
#define TEST_VARIANT_ITERATOR_008
#define TEST_VARIANT_ITERATOR_009
#define TEST_VARIANT_ITERATOR_010
#define TEST_VARIANT_ITERATOR_011
#define TEST_VARIANT_ITERATOR_012
#define TEST_VARIANT_ITERATOR_013
#define TEST_VARIANT_ITERATOR_014
#define TEST_VARIANT_ITERATOR_015
#define TEST_VARIANT_ITERATOR_016
#define TEST_VARIANT_ITERATOR_017
#define TEST_VARIANT_ITERATOR_018
#define TEST_VARIANT_ITERATOR_019
#define TEST_VARIANT_ITERATOR_020
#define TEST_VARIANT_ITERATOR_021
#define TEST_VARIANT_ITERATOR_022
#define TEST_VARIANT_ITERATOR_023
#define TEST_VARIANT_ITERATOR_024
#define TEST_VARIANT_ITERATOR_025
#define TEST_VARIANT_ITERATOR_026
#define TEST_VARIANT_ITERATOR_027
#define TEST_VARIANT_ITERATOR_028
#define TEST_VARIANT_ITERATOR_029
#define TEST_VARIANT_ITERATOR_030
#define TEST_VARIANT_ITERATOR_031
#define TEST_VARIANT_ITERATOR_032

using namespace variant_detail;

//------------------------------------------------------------------------------------------------------//
namespace{

    typedef variant_detail::V::I8         I8;
    typedef variant_detail::V::I16        I16;
    typedef variant_detail::V::I32        I32;
    typedef variant_detail::V::I64        I64;
    typedef variant_detail::V::U8         U8;
    typedef variant_detail::V::U16        U16;
    typedef variant_detail::V::U32        U32;
    typedef variant_detail::V::U64        U64;
    typedef variant_detail::V::F32        F32;
    typedef variant_detail::V::F64        F64;
    typedef variant_detail::V::Byte       Byte;
    typedef variant_detail::V::WChar      WChar;
    typedef variant_detail::V::Str        Str;
    typedef variant_detail::V::WStr       WStr;
    typedef variant_detail::V::Vec        Vec;
    typedef variant_detail::V::Map        Map;
    typedef variant_detail::V::Blob       Blob;
    typedef variant_detail::V::List       List;

    template<class T> void MostBe(const Variant& v, const T& val )
    {
        const bool can = v.Is<T>();
        EXPECT_EQ(true, can);
        if(!can)
            return;
        EXPECT_EQ(val,  v.Get<T>() );
    }
    template<class T> void MostBe(const Variant& v)
    {
        EXPECT_EQ(true, v.Is<T>());
    }

    template<class Iter, class T> void MostBe(Iter& it, const T& val )
    {
        const bool can = it->template Is<T>();

        EXPECT_EQ(true, can);
        if(!can)
            return;
        EXPECT_EQ(val,  it->template Get<T>() );
    }
    template<class Iter, class T> void MostBe(Iter& it)
    {
        EXPECT_EQ(true, it->template Is<T>());
    }



}//namespace



//------------------------------------------------------------------------------------------------------//

#ifdef TEST_VARIANT_ITERATOR_000
TEST(Variant, Iterator_000)
{
    Vec vec; //ViewFullContainer(vec);

    for(size_t n = 0; n<5;++n)
        vec.emplace_back( Variant::I32(n) );

    Variant val = vec;

    size_t n=0;
    for( Iterator it = val, end; it!=end; ++it, ++n)
    {
        const auto re = it->Get<Variant::I32>();
        const auto ke = it.GetKey();

        EXPECT_EQ(n,  re );
        EXPECT_EQ("", ke );
    }
    EXPECT_EQ(5, n);
}
#endif // TEST_VARIANT_ITERATOR_000

#ifdef TEST_VARIANT_ITERATOR_001
TEST(Variant, Iterator_001)
{
    Map m;
    m["one"] = Variant::I32(10);
    m["two"] = true;
    //ViewFullContainer(m);

    Vec vec1;
    Vec vec2;
    size_t n=0;
    Variant val = m;
    for( Iterator it = val, end; it!=end; ++it,++n)
        vec1.emplace_back( *it ),
        vec2.emplace_back( it.GetKey() );
    EXPECT_EQ(2, n);

    auto re11 = vec1[0].Get<Variant::I32>();
    auto re21 = vec1[1].Get<bool>();

    auto re12 = vec2[0].Get<Variant::Str>();
    auto re22 = vec2[1].Get<Variant::Str>();

    EXPECT_EQ(10,    re11 );
    EXPECT_EQ(true,  re21 );

    EXPECT_EQ("one", re12 );
    EXPECT_EQ("two", re22 );
}
#endif // TEST_VARIANT_ITERATOR_001

#ifdef TEST_VARIANT_ITERATOR_002
TEST(Variant, Iterator_002)
{
    size_t n=0;
    Variant::Str key;
    Variant::I32 val;
    Variant v=Variant::I32(10);
    for( Iterator it = v, end; it!=end; ++it,++n)
        key = it.GetKey(),
        val = it.GetVariant();
    EXPECT_EQ(1, n);
    EXPECT_EQ(10, val );
    EXPECT_EQ("", key );
}
#endif // TEST_VARIANT_ITERATOR_002

#ifdef TEST_VARIANT_ITERATOR_003
TEST(Variant, Iterator_003)
{
    Map m;
    m["one"] = Variant::I32(10);
    m["two"] = true;

    Vec val;
    size_t n=0;
    Variant v = m;

    for( const auto& it: v)
        val.emplace_back( it ),
        ++n;

    EXPECT_EQ(2, n);
    auto v1 = val[0].Get<Variant::I32>();
    auto v2 = val[1].Get<bool>();
    EXPECT_EQ(10,    v1 );
    EXPECT_EQ(true,  v2 );
}
#endif // TEST_VARIANT_ITERATOR_003

#ifdef TEST_VARIANT_ITERATOR_004
TEST(Variant, Iterator_004)
{
    List l;
    l.push_back(10);
    l.push_back(true);

    Vec val;
    size_t n=0;
    Variant v = l;
    for(const auto& it: v)
        val.emplace_back( it ),
        ++n;

    EXPECT_EQ(2, n);
    auto v1 = val[0].Get<Variant::I32>();
    auto v2 = val[1].Get<bool>();
    EXPECT_EQ(10,    v1 );
    EXPECT_EQ(true,  v2 );
}
#endif // TEST_VARIANT_ITERATOR_004

#ifdef TEST_VARIANT_ITERATOR_005
TEST(Variant, Iterator_005)
{
     Vec vec;
     vec.emplace_back(1);
     vec.emplace_back(2);
     vec.emplace_back(3);
     vec.emplace_back(4);
     vec.emplace_back(5);

     size_t n=5;
     Variant v = vec;
     for( ReverseIterator it = v, end; it!=end; ++it,--n)
     {
         const auto re = it->Get<Variant::I32>();
         const auto ke = it.GetKey();
         EXPECT_EQ(n,  re );
         EXPECT_EQ("", ke );
     }
     EXPECT_EQ(0, n);
}
#endif // TEST_VARIANT_ITERATOR_005

#ifdef TEST_VARIANT_ITERATOR_006
TEST(Variant, Iterator_006)
{
    Map m;
    m["one"] = Variant::I32(10);
    m["two"] = true;

    Vec val;
    Vec key;
    size_t n=2;
    Variant v = m;
    for( ReverseIterator it = v, end; it!=end; ++it,--n)
        val.emplace_back( *it ),
        key.emplace_back( it.GetKey() );
    EXPECT_EQ(0, n);

    auto v1 = val[0].Get<bool>();
    auto v2 = val[1].Get<Variant::I32>();

    auto k1 = key[0].Get<Variant::Str>();
    auto k2 = key[1].Get<Variant::Str>();

    EXPECT_EQ(true, v1 );
    EXPECT_EQ(10,   v2 );

    EXPECT_EQ("two", k1 );
    EXPECT_EQ("one", k2 );
}
#endif // TEST_VARIANT_ITERATOR_006

#ifdef TEST_VARIANT_ITERATOR_007
TEST(Variant, Iterator_007)
{
    size_t n=0;
    Variant::Str key;
    bool val;

    Variant v=Variant::Record("one", true);
    for( Iterator it = v, end; it!=end; ++it,++n)
        key = it.GetKey(),
        val = it.GetVariant();
    EXPECT_EQ(1, n);
    EXPECT_EQ(true, val );
    EXPECT_EQ("",   key );
}
#endif // TEST_VARIANT_ITERATOR_007

#ifdef TEST_VARIANT_ITERATOR_008
TEST(Variant, Iterator_008)
{
    Vec vec;
    vec.emplace_back(0);
    vec.emplace_back(1);
    vec.emplace_back(2);
    vec.emplace_back(3);
    vec.emplace_back(4);
    Variant v = vec;
//    for( ConstRecursiveIterator it = v, end; it!=end; ++it)
//        cout<< "'"<<it.GetKey()<<"'"<<" : "<< it.GetVariant()<<endl;

    ConstRecursiveIterator it = v;
    MostBe<ConstRecursiveIterator, Vec>(it);    ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 0); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 1); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 2); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 3); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 4); ++it;
    EXPECT_EQ(true, it.IsEnd());
    EXPECT_EQ(true, it.Empty());
}
#endif // TEST_VARIANT_ITERATOR_008

#ifdef TEST_VARIANT_ITERATOR_009
TEST(Variant, Iterator_009)
{
    Vec vec;
    vec.emplace_back(1);
    vec.emplace_back(2);
    vec.emplace_back(3);
    vec.emplace_back(4);
    vec.emplace_back(5);

    Variant v;
    v["hello"]["1"]   = I32(1);
    v["hello"]["2"]   = vec;
    v["world"]["one"] = I32(3);

    ConstRecursiveIterator it = v;
    MostBe<ConstRecursiveIterator, Map>(it);    ++it;
    MostBe<ConstRecursiveIterator, Map>(it);    ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 1); ++it;
    MostBe<ConstRecursiveIterator, Vec>(it);    ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 1); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 2); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 3); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 4); ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 5); ++it;
    MostBe<ConstRecursiveIterator, Map>(it);    ++it;
    MostBe<ConstRecursiveIterator, I32>(it, 3); ++it;
    EXPECT_EQ(true, it.IsEnd());
    EXPECT_EQ(true, it.Empty());

//    for( ConstRecursiveIterator it = v, end; it!=end; ++it)
//    {
//        const auto& key = it.GetKey();
//        if(!key.empty())
//            cout<< "'"<<key<<"' : ";
//        cout<< it.GetVariant()<<endl;
//    }
}
#endif // TEST_VARIANT_ITERATOR_009

#ifdef TEST_VARIANT_ITERATOR_010
TEST(Variant, Iterator_010)
{
    Vec vec;
    vec.emplace_back(1);
    vec.emplace_back(2);
    vec.emplace_back(3);
    vec.emplace_back(4);
    vec.emplace_back(5);

    Variant v;
    v["hello"]["1"]   = I32(1);
    v["hello"]["2"]   = vec;
    v["world"]["one"] = I32(3);

    RecursiveIterator it = v;
    MostBe<RecursiveIterator, Map>(it);    ++it;
    MostBe<RecursiveIterator, Map>(it);    ++it;
    MostBe<RecursiveIterator, I32>(it, 1); ++it;
    MostBe<RecursiveIterator, Vec>(it);    ++it;
    MostBe<RecursiveIterator, I32>(it, 1); ++it;
    MostBe<RecursiveIterator, I32>(it, 2); ++it;
    MostBe<RecursiveIterator, I32>(it, 3); ++it;
    MostBe<RecursiveIterator, I32>(it, 4); ++it;
    MostBe<RecursiveIterator, I32>(it, 5); ++it;
    MostBe<RecursiveIterator, Map>(it);    ++it;
    MostBe<RecursiveIterator, I32>(it, 3); ++it;
    EXPECT_EQ(true, it.IsEnd());
    EXPECT_EQ(true, it.Empty());

//    for( RecursiveIterator it = v, end; it!=end; ++it)
//    {
//        const auto& key = it.GetKey();
//        if(!key.empty())
//            cout<< "'"<<key<<"' : ";
//        cout<< it.GetVariant()<<endl;
//    }
}
#endif // TEST_VARIANT_ITERATOR_010

#ifdef TEST_VARIANT_ITERATOR_011
TEST(Variant, Iterator_011)
{
    Variant v;
    v[0] = Variant::I32(0);
    v[1] = true;
    v[2][0] = Variant::I32(1);

    v[2][1][0] ="hello";
    v[2][1][1] ="world";
    v[3][0][0] = Variant::I32(23);
    v[3][0][1][0] = Variant::I32(24);
    v[3][0][1][1] = true;
    v[3][1] = Variant::I32(3);
    v[3][2] = true;
    //cout << ToHummanStyle(v) << endl;

    auto it  = v.crecbegin();
    auto end = v.crecend();

    MostBe<ConstRecursiveIterator, Vec>(it);          ++it;
    MostBe<ConstRecursiveIterator, I32>(it,0);        ++it;
    MostBe<ConstRecursiveIterator, bool>(it,true);    ++it;
    MostBe<ConstRecursiveIterator, Vec>(it);          ++it;
    MostBe<ConstRecursiveIterator, I32>(it,1);        ++it;
    MostBe<ConstRecursiveIterator, Vec>(it);          ++it;
    MostBe<ConstRecursiveIterator, Str>(it,"hello");  ++it;
    MostBe<ConstRecursiveIterator, Str>(it,"world");  ++it;
    MostBe<ConstRecursiveIterator, Vec>(it);          ++it;
    MostBe<ConstRecursiveIterator, Vec>(it);          ++it;
    MostBe<ConstRecursiveIterator, I32>(it,23);       ++it;
    MostBe<ConstRecursiveIterator, Vec>(it);          ++it;
    MostBe<ConstRecursiveIterator, I32>(it,24);       ++it;
    MostBe<ConstRecursiveIterator, bool>(it,true);    ++it;
    MostBe<ConstRecursiveIterator, I32>(it,3);        ++it;
    MostBe<ConstRecursiveIterator, bool>(it,true);    ++it;
    EXPECT_EQ(true, it.IsEnd());
    EXPECT_EQ(true, it.Empty());
    EXPECT_EQ(true, it==end);

}
#endif // TEST_VARIANT_ITERATOR_011

#ifdef TEST_VARIANT_ITERATOR_012
TEST(Variant, Iterator_012)
{
    Variant v;
    v[0] = Variant::I32(0);
    v[1] = true;
    v[2][0] = Variant::I32(1);
    v[2][1][0] ="hello";
    v[2][1][1] ="world";
    v[3][0][0] = Variant::I32(23);
    v[3][0][1][0] = Variant::I32(24);
    v[3][0][1][1] = 'c';
    v[3][1] = Variant::I32(3);
    v[3][2] = "true";

    //cout << ToHummanStyle(v) << endl;

#if 0
vec:
 |-15--0
 |-14--true
 |-13--vec:
 |      |-12--1
 |      |-11--vec:
 |             |-10--"hello"
 |             |-9---"world"
 |-8--vec:
       |-7--vec:
       |     |-6--23
       |     |-5--vec:
       |           |-4--24
       |           |-3--'c'
       |-2--3
       |-1--"true"

[  0,
   true,
   [ 1,
     [ "hello",
       "world" 
     ]
   ],
   [ [ 23,
       [ 24,
         "c"
       ]
     ],
     3,
     "true"
   ],
   { "one" : 10,
     "two" : [ 1,
               2,
               3
             ]
   }
]

#endif

    auto beg  = v.crecbegin();
    auto it   = v.crecend();
    --it; MostBe<ConstRecursiveIterator, Str>(it,"true");
    --it; MostBe<ConstRecursiveIterator, I32>(it,3);
    --it; MostBe<ConstRecursiveIterator, char>(it,'c');
    --it; MostBe<ConstRecursiveIterator, I32>(it,24);
    --it; MostBe<ConstRecursiveIterator, Vec>(it);
    --it; MostBe<ConstRecursiveIterator, I32>(it,23);
    --it; MostBe<ConstRecursiveIterator, Vec>(it);
    --it; MostBe<ConstRecursiveIterator, Vec>(it);
    --it; MostBe<ConstRecursiveIterator, Str>(it,"world");
    --it; MostBe<ConstRecursiveIterator, Str>(it,"hello");
    --it; MostBe<ConstRecursiveIterator, Vec>(it);
    --it; MostBe<ConstRecursiveIterator, I32>(it,1);
    --it; MostBe<ConstRecursiveIterator, Vec>(it);
    --it; MostBe<ConstRecursiveIterator, bool>(it,true);
    --it; MostBe<ConstRecursiveIterator, I32>(it,0);
    --it; MostBe<ConstRecursiveIterator, Vec>(it);
    EXPECT_EQ(true, it.IsBeg());

//    auto _beg  = v.crecbegin();
//    auto _it   = v.crecend();

//    for(;;)
//    {
//        --_it;
//        cout<< *_it<<endl;
//        if(_it == _beg)
//            break;
//    }

}
#endif // TEST_VARIANT_ITERATOR_012

#ifdef TEST_VARIANT_ITERATOR_013
TEST(Variant, Iterator_013)
{
    Vec vec;
    vec.push_back( V::I32(10) );
    vec.push_back( V::I32(20) );
    Variant v = vec;

    auto it = v.end();

    EXPECT_EQ(true, it.IsEnd() );
    EXPECT_EQ(false, it.IsBeg() );

    --it;
    EXPECT_EQ(20,    it->Get<V::I32>() );
    EXPECT_EQ(false, it.IsEnd() );
    EXPECT_EQ(false, it.IsBeg() );

    --it;
    EXPECT_EQ(10,    it->Get<V::I32>() );
    EXPECT_EQ(false, it.IsEnd() );
    EXPECT_EQ(true,  it.IsBeg() );
}
#endif // TEST_VARIANT_ITERATOR_013

#ifdef TEST_VARIANT_ITERATOR_014
TEST(Variant, Iterator_014)
{
    Vec vec;
    vec.push_back( V::I32(10) );
    vec.push_back( V::I32(20) );
    Variant v = vec;

    auto it = v.cend();

    EXPECT_EQ(true, it.IsEnd() );
    EXPECT_EQ(false, it.IsBeg() );

    --it;
    EXPECT_EQ(20,    it->Get<V::I32>() );
    EXPECT_EQ(false, it.IsEnd() );
    EXPECT_EQ(false, it.IsBeg() );

    --it;
    EXPECT_EQ(10,    it->Get<V::I32>() );
    EXPECT_EQ(false, it.IsEnd() );
    EXPECT_EQ(true,  it.IsBeg() );
}
#endif // TEST_VARIANT_ITERATOR_014

#ifdef TEST_VARIANT_ITERATOR_015
TEST(Variant, Iterator_015)
{
    Variant v; v["hello"] = Variant::Vec(3,I32(3) );
    Variant::recursive_iterator it(v);

    //cout<< v <<endl;

    Variant& r =  *it;
    cout<< r <<endl;

    //const bool ismap = it->Is<Variant::Map>();

    EXPECT_EQ( true, it->Is<Variant::Map>() ); ++it;
    EXPECT_EQ( true, it->Is<Variant::Vec>() ); ++it;
    EXPECT_EQ( true, it->Is<Variant::I32>() ); ++it;
    EXPECT_EQ( true, it->Is<Variant::I32>() ); ++it;
    EXPECT_EQ( true, it->Is<Variant::I32>() ); ++it;
    EXPECT_EQ( true, it == Variant::recursive_iterator() );

    it = v;
    size_t n=0;
    while(it!= Variant::recursive_iterator() )
        ++it, ++n;
    EXPECT_EQ(5, n );
}
#endif // TEST_VARIANT_ITERATOR_015


#ifdef TEST_VARIANT_ITERATOR_016
TEST(Variant, Iterator_016)
{
    std::vector<Str> argumetns(3);
    Variant args;
    args[0]="one";
    args[1]="two";
    args[2]="bar";

//     for(auto it = args.begin(), auto end = args.end(); it != end; ++it)
//     {
// 
//     }

// 
//     Str v;
//     
//     v = args[0];

    //std::vector<Str>::iterator it = argumetns.begin();
    //*it = args[0];

    //std::copy(args.begin(), args.end(), argumetns.begin());
   
    
}
#endif // TEST_VARIANT_ITERATOR_016

#ifdef TEST_VARIANT_ITERATOR_017
#endif // TEST_VARIANT_ITERATOR_017

#ifdef TEST_VARIANT_ITERATOR_018
#endif // TEST_VARIANT_ITERATOR_018

#ifdef TEST_VARIANT_ITERATOR_019
#endif // TEST_VARIANT_ITERATOR_019

#ifdef TEST_VARIANT_ITERATOR_020
#endif // TEST_VARIANT_ITERATOR_020

#ifdef TEST_VARIANT_ITERATOR_021
#endif // TEST_VARIANT_ITERATOR_021

#ifdef TEST_VARIANT_ITERATOR_022
#endif // TEST_VARIANT_ITERATOR_022

#ifdef TEST_VARIANT_ITERATOR_023
#endif // TEST_VARIANT_ITERATOR_023

#ifdef TEST_VARIANT_ITERATOR_024
#endif // TEST_VARIANT_ITERATOR_024

#ifdef TEST_VARIANT_ITERATOR_025
#endif // TEST_VARIANT_ITERATOR_025

#ifdef TEST_VARIANT_ITERATOR_026
#endif // TEST_VARIANT_ITERATOR_026

#ifdef TEST_VARIANT_ITERATOR_027
#endif // TEST_VARIANT_ITERATOR_027

#ifdef TEST_VARIANT_ITERATOR_028
#endif // TEST_VARIANT_ITERATOR_029

#ifdef TEST_VARIANT_ITERATOR_030
#endif // TEST_VARIANT_ITERATOR_030

#ifdef TEST_VARIANT_ITERATOR_031
#endif // TEST_VARIANT_ITERATOR_031

#ifdef TEST_VARIANT_ITERATOR_032
#endif // TEST_VARIANT_ITERATOR_032

#endif

//#include "default_warning.h"

